package com.zgw.fireline.base.common;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

public class FileUtil {

	public static void copy(File sourceFolder, File targetFolder)
			throws IOException {
		Assert.isTrue(sourceFolder.isDirectory());
		Assert.isTrue(targetFolder.isDirectory());
		File s, t;
		for (String name : targetFolder.list()) {
			s = new File(sourceFolder, name);
			t = new File(targetFolder, name);
			if (!s.exists())
				continue;
			if (t.exists() && t.isDirectory() != s.isDirectory()) {
				clear(t);
			}
			if (s.isDirectory()) {
				t.mkdir();
				copy(s, t);
			} else {
				copy(new FileInputStream(s), new FileOutputStream(t));
			}
		}
	}

	public static boolean isExixts(URL url) {
		try {
			url.openStream().close();
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	public static void addFileToZip(File localjar, File root)
			throws IOException, ArchiveException {

		ByteOutputStream bufferjar = new ByteOutputStream();
		InputStream finput = new FileInputStream(localjar);
		bufferjar.write(finput);
		finput.close();

		ZipArchiveInputStream zipinput = new ZipArchiveInputStream(
				new ByteArrayInputStream(bufferjar.getBytes()));
		ZipArchiveOutputStream zipout = new ZipArchiveOutputStream(localjar);

		zipout.setEncoding("UTF-8");
		ZipArchiveEntry ze;
		List<String> copyitems = new ArrayList<String>();
		List<File> files = getChildrens(root, new ArrayList<File>());
		for (File f : files) {
			if (!f.exists())
				continue;
			ze = new ZipArchiveEntry(getEntryName(f, root.getPath()));// 获取每个文件相对路径,作为在ZIP中路径
			copyitems.add(ze.getName());
			zipout.putArchiveEntry(ze);
			// folder
			if (ze.isDirectory()) {
				zipout.closeArchiveEntry();
				continue;
			}
			// file
			FileInputStream fis = new FileInputStream(f);
			IOUtils.copy(fis, zipout, 4096);
			fis.close();
			zipout.closeArchiveEntry();
		}
		// 拷贝原来的
		while ((ze = zipinput.getNextZipEntry()) != null) {
			if (!copyitems.contains(ze.getName())) {
				zipout.putArchiveEntry(ze);
				if (!ze.isDirectory()) {
					IOUtils.copy(zipinput, zipout, 4096);
				}
				zipout.closeArchiveEntry();
			}
		}
		zipout.close();
		zipinput.close();
	}

	private static List<File> getChildrens(File root, List<File> list) {
		Assert.isTrue(root.isDirectory());
		for (File f : root.listFiles()) {
			if (!f.exists())
				continue;
			if (f.isDirectory())
				getChildrens(f, list);
			else
				list.add(f);
		}
		return list;
	}

	private static String getEntryName(File f, String rootPath) {
		String entryName;
		String fPath = f.getPath();
		if (fPath.indexOf(rootPath) != -1)
			entryName = fPath.substring(rootPath.length() + 1);
		else
			entryName = f.getName();

		if (f.isDirectory())
			entryName += "/";// "/"后缀表示entry是文件夹
		return entryName;
	}

	public static void copy(InputStream input, FileOutputStream output)
			throws IOException {
		try {
			IOUtils.copy(input, output, 4096);
		} finally {
			input.close();
			output.close();
		}
	}

	public static boolean clear(java.io.File root) {
		boolean result = clearChildren(root);
		try {
			if (root.exists())
				result &= root.delete();
		} catch (Exception e) {
			result = false;
		}
		return result;
	}

	public static boolean clearChildren(java.io.File root) {
		boolean result = true;
		if (root.isDirectory()) {
			String[] list = root.list();
			// for some unknown reason, list() can return null.
			// Just skip the children If it does.
			if (list != null)
				for (int i = 0; i < list.length; i++)
					result &= clear(new java.io.File(root, list[i]));
		}
		return result;
	}
}
